﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Management;
using System.IO;
using System.ComponentModel;
using System.ServiceProcess;
using System.Collections;

namespace AleCheck
{
    public class CPU_Check
    {
        PerformanceCounter cpuCounter;
        PerformanceCounter ramCounter;

        [Description("Return Total CPU Usage in %")]
        public float CpuUsage
        {
            get
            {
                if (cpuCounter == null)
                {
                    cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                }
                return (cpuCounter.NextValue());
            }
        }

         public string getAvailableRAM(){
            ramCounter = new PerformanceCounter("Memory", "Available MBytes");
           return ramCounter.NextValue()+"MB";
          }
         public string getCurrentCpuUsage()
         {
             cpuCounter = new PerformanceCounter();
             cpuCounter.CategoryName = "Processor";
             cpuCounter.CounterName = "% Processor Time";
             cpuCounter.InstanceName = "_Total";
             return cpuCounter.NextValue() + "%";
         }
         [Description("Return Total Amount of RAM in the System")]
         public static double TotalRam
         {
             get
             {
                 double Ram_Bytes = 0;
                 using (ManagementObjectSearcher Search = new ManagementObjectSearcher("Select * From Win32_ComputerSystem")) {
                     foreach (ManagementObject Mobject in Search.Get()) {
                         Ram_Bytes = (Convert.ToDouble(Mobject["TotalPhysicalMemory"]));
                     }
                 }
                 return (Ram_Bytes / 1048576);
             }
         }
    }

    public class Disk_Check
    {
        [DllImport("kernel32.dll", EntryPoint = "GetDiskFreeSpaceExA")]
        private static extern long GetDiskFreeSpaceEx(string lpDirectoryName,
          out long lpFreeBytesAvailableToCaller,
          out long lpTotalNumberOfBytes,
          out long lpTotalNumberOfFreeBytes);
        internal long _GetFreeDiskSpace(string driveName)
        {
            long totalBytes, freeBytes, freeBytesAvail, result;

            if (!Directory.Exists(driveName))
                throw new ArgumentException("Invalid Drive " + driveName);

            result = GetDiskFreeSpaceEx(driveName,
                out freeBytesAvail,
                out totalBytes,
                out freeBytes);

            return freeBytesAvail;

        }
        public string GetFreeDiskSpace(string driveName)
        {
            try
            {
                double dResult = (double)_GetFreeDiskSpace(driveName);
                dResult = (dResult / 1024) / 1024;

                return dResult.ToString("###,###,##0.00");
            }
            catch (ArgumentException)
            {
                return "";
            }
        }

        public static bool FileNotInUse(string path)
        {
            try
            {
                //Just opening the file as open/create
                using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
                {
                    //If required we can check for read/write by using fs.CanRead or fs.CanWrite
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

    }

    public class System_Check
    {
        //Create a structure to pass the reference to the dll.
        public struct LASTINPUTINFO
        {
            public uint cbSize;
            public uint dwTime;
        }


        //Importing the Dll & declaring the neccessary funtion
        [DllImport("user32.dll")]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);


        //Function to return the idle time
        [Description("Return System Idle in Seconds")]
        public static int IdleTime
        {
            get
            {
                //Creating the object of the structure
                LASTINPUTINFO lastone = new LASTINPUTINFO();

                //Initialising  
                lastone.cbSize = (uint)Marshal.SizeOf(lastone);
                lastone.dwTime = 0;

                int idleTime = 0;

                //To get the total time after starting the system.
                int tickCount = Environment.TickCount;

                //Calling the dll funtion and getting the last input time.
                if (GetLastInputInfo(ref lastone))
                {
                    idleTime = tickCount - (int)lastone.dwTime;
                    return (idleTime / 1000);
                }
                else
                    return 0;
            }
        }


        [Description("Return System Uptime in Seconds")]
        public static int UpTime
        {
            get
            {
                int systemUptime = Environment.TickCount;
                return (systemUptime / 1000);
            }
        }

        public static bool RegKeyExist(int KindOfKey, string strKey)
        {
            Microsoft.Win32.RegistryKey key = null;
            switch (KindOfKey)
            {
                case 1:
                    key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(strKey);
                    break;
                case 2:
                    key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(strKey);
                    break;
                case 3:
                    key = Microsoft.Win32.Registry.CurrentConfig.OpenSubKey(strKey);
                    break;
                case 4:
                    key = Microsoft.Win32.Registry.Users.OpenSubKey(strKey);
                    break;
                case 5:
                    key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(strKey);
                    break;
            }
            if (key == null)
                return false;
            else {
                key.Close();
                return true;
            }
        }

        public static bool IsServiceInstalled(string serviceName)
        {
            // get list of Windows services
            ServiceController[] services = ServiceController.GetServices();

            // try to find service name
            foreach (ServiceController service in services)
            {
                if (service.ServiceName == serviceName)
                    return true;
            }
            return false;
        }

        public static bool ProcessExist(string processname)
        {
            Process[] aProc = Process.GetProcessesByName(processname);
            
            if (aProc.Length > 0)
                return true;

            else return false;
        }

        //Method to get name of process in NTVDM 16bit Subsystem
        //Title of the command prompt
        public static void Enum16BitProcesses()
        {
            // create a delegate for the callback function
            ProcessTasksExDelegate procTasksDlgt = new ProcessTasksExDelegate(System_Check.ProcessTasksEx);

            // this part is the easy way of getting NTVDM procs
            foreach (var ntvdm in Process.GetProcessesByName("ntvdm"))
            {
                Console.WriteLine("ntvdm id = {0}", ntvdm.Id);

                int apiRet = VDMEnumTaskWOWEx(ntvdm.Id, procTasksDlgt, IntPtr.Zero);

                //Console.WriteLine("EnumTaskWOW returns {0}", apiRet);

            }

        }

        public static string[] Get16BitProcess()
        {
            ArrayList a1 = new ArrayList();
            // create a delegate for the callback function
            ProcessTasksExDelegate procTasksDlgt = new ProcessTasksExDelegate(System_Check.ProcessTasksEx);
            // this part is the easy way of getting NTVDM procs
            foreach (var ntvdm in Process.GetProcessesByName("ntvdm"))
            {
                a1.Add(ntvdm.MainWindowTitle);
            }
            return a1.ToArray(typeof(string)) as string[];
        }
       
         // declaration of API function callback

        public delegate bool ProcessTasksExDelegate(

            int ThreadId,
            IntPtr hMod16,

            IntPtr hTask16,
            IntPtr ptrModName,

            IntPtr ptrFileName,
            IntPtr UserDefined

            );

        // the actual function that fails on Vista so far
        [DllImport("VdmDbg.dll", SetLastError = false, CharSet = CharSet.Auto)]

        public static extern int VDMEnumTaskWOWEx(

            int processId,
            ProcessTasksExDelegate TaskEnumProc,

            IntPtr lparam);

        // the actual callback function, on Vista never gets called

        public static bool ProcessTasksEx(

            int ThreadId,
            IntPtr hMod16,

            IntPtr hTask16,
            IntPtr ptrModName,

            IntPtr ptrFileName,
            IntPtr UserDefined

            )
        {
            string filename = Marshal.PtrToStringAuto(ptrFileName);

            Console.WriteLine("Filename of WOW16 process: {0}", filename);

            return false;       // false continues enumeration

        }

        /// <summary>
        /// Method That Check a File until is Completed,
        /// Useful with FileSystemWatcher Created
        /// </summary>
        /// <param name="fileName">File Name To check</param>
        public static bool WaitUntilFileIsCompleted(string fileName)
        {
            while (true)
            {
                try
                {
                    FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
                    fs.Close();
                    return true;
                }
                catch (FileNotFoundException)
                {
                    return false;
                }
                catch (IOException)
                {
                    System.Threading.Thread.Sleep(1000);
                    continue;
                }
            }
        }
        /// <summary>
        /// Wait Until a File is Completely created
        /// </summary>
        /// <param name="fileName">File to monitor</param>
        /// <param name="maxWait">Timeout : Max Milliseconds to Wait</param>
        public void WaitUntilFileIsCompleted(string fileName, int maxWait)
        {
            int wait = 0;
            while (true)
            {
                try
                {
                    FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
                    fs.Close(); // no exception was thrown so close the stream
                    fs.Dispose();
                    return; // and return - now the file is complete
                }
                catch (IOException)
                {
                    wait += 100;
                    System.Threading.Thread.Sleep(100); // wait 100ms for completion
                    if (wait > maxWait)
                        throw new ApplicationException("Timeout reached waiting for completion of file.");
                }
            }
        }
    }

       
    public class LAN_Check
    {
        [DllImport("wininet.dll")]
        private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

        public static bool IsConnectedToInternet
        {
            get
            {
                int Desc;
                return InternetGetConnectedState(out Desc, 0);
            }
        }

        // Ping www.google.com to check if the user has a internet connection.
        [Description("Return if the Internet Connection is alive - Ping 208.69.34.231(Google)")]
        public static bool PingTest
        {
            get
            {
                using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping()) {

                    System.Net.NetworkInformation.PingReply pingStatus = ping.Send(System.Net.IPAddress.Parse("208.69.34.231"));

                    if (pingStatus.Status == System.Net.NetworkInformation.IPStatus.Success)
                        return true;
                    else
                        return false;
                }
            }
        }
        //For Test Lan use This System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
    }

}

namespace AleUtil
{
    #region ProcessUtility Class
    [StructLayout(LayoutKind.Sequential)]
    internal struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public uint dwProcessId;
        public uint dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct SECURITY_ATTRIBUTES
    {
        public uint nLength;
        public IntPtr lpSecurityDescriptor;
        public bool bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFO
    {
        public uint cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public uint dwX;
        public uint dwY;
        public uint dwXSize;
        public uint dwYSize;
        public uint dwXCountChars;
        public uint dwYCountChars;
        public uint dwFillAttribute;
        public uint dwFlags;
        public short wShowWindow;
        public short cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;

    }

    internal enum SECURITY_IMPERSONATION_LEVEL
    {
        SecurityAnonymous,
        SecurityIdentification,
        SecurityImpersonation,
        SecurityDelegation
    }

    internal enum TOKEN_TYPE
    {
        TokenPrimary = 1,
        TokenImpersonation
    }

    public class ProcessAsUser
    {

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool CreateProcessAsUser(
        IntPtr hToken,
        string lpApplicationName,
        string lpCommandLine,
        ref SECURITY_ATTRIBUTES lpProcessAttributes,
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        bool bInheritHandles,
        uint dwCreationFlags,
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        ref STARTUPINFO lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);

        [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx", SetLastError = true)]
        private static extern bool DuplicateTokenEx(
        IntPtr hExistingToken,
        uint dwDesiredAccess,
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        Int32 ImpersonationLevel,
        Int32 dwTokenType,
        ref IntPtr phNewToken);

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool OpenProcessToken(
        IntPtr ProcessHandle,
        UInt32 DesiredAccess,
        ref IntPtr TokenHandle);

        [DllImport("userenv.dll", SetLastError = true)]
        private static extern bool CreateEnvironmentBlock(
        ref IntPtr lpEnvironment,
        IntPtr hToken,
        bool bInherit);

        [DllImport("userenv.dll", SetLastError = true)]
        private static extern bool DestroyEnvironmentBlock(
        IntPtr lpEnvironment);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(
        IntPtr hObject);

        private const short SW_SHOW = 5;
        private const uint TOKEN_QUERY = 0x0008;
        private const uint TOKEN_DUPLICATE = 0x0002;
        private const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
        private const int GENERIC_ALL_ACCESS = 0x10000000;
        private const int STARTF_USESHOWWINDOW = 0x00000001;
        private const int STARTF_FORCEONFEEDBACK = 0x00000040;
        private const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400;
        private const int STARTF_RUNFULLSCREEN = 0x00000020;

        private static bool LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock)
        {
            bool result = false;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            SECURITY_ATTRIBUTES saProcess = new SECURITY_ATTRIBUTES();
            SECURITY_ATTRIBUTES saThread = new SECURITY_ATTRIBUTES();
            saProcess.nLength = (uint)Marshal.SizeOf(saProcess);
            saThread.nLength = (uint)Marshal.SizeOf(saThread);
           
            STARTUPINFO si = new STARTUPINFO();
            si.cb = (uint)Marshal.SizeOf(si);

            //if this member is NULL, the new process inherits the desktop
            //and window station of its parent process. If this member is
            //an empty string, the process does not inherit the desktop and
            //window station of its parent process; instead, the system
            //determines if a new desktop and window station need to be created.
            //If the impersonated user already has a desktop, the system uses the
            //existing desktop.

            si.lpDesktop = @"WinSta0\Default"; //Modify as needed
            si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
            si.wShowWindow = SW_SHOW;
            
            //Set other si properties as required.

            result = CreateProcessAsUser(
            token,
            null,
            cmdLine,
            ref saProcess,
            ref saThread,
            false,
            CREATE_UNICODE_ENVIRONMENT,
            envBlock,
            null,
            ref si,
            out pi);

            if (result == false)
            {
                int error = Marshal.GetLastWin32Error();
                string message = String.Format("CreateProcessAsUser Error: {0}", error);
                Debug.WriteLine(message);

            }

            return result;
        }

        /// <summary>
        /// LaunchProcess As User Overloaded for Window Mode 
        /// </summary>
        /// <param name="cmdLine"></param>
        /// <param name="token"></param>
        /// <param name="envBlock"></param>
        /// <param name="WindowMode"></param>
        /// <returns></returns>
        private static bool LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock,uint WindowMode)
        {
            bool result = false;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            SECURITY_ATTRIBUTES saProcess = new SECURITY_ATTRIBUTES();
            SECURITY_ATTRIBUTES saThread = new SECURITY_ATTRIBUTES();
            saProcess.nLength = (uint)Marshal.SizeOf(saProcess);
            saThread.nLength = (uint)Marshal.SizeOf(saThread);

            STARTUPINFO si = new STARTUPINFO();
            si.cb = (uint)Marshal.SizeOf(si);
            
            //if this member is NULL, the new process inherits the desktop
            //and window station of its parent process. If this member is
            //an empty string, the process does not inherit the desktop and
            //window station of its parent process; instead, the system
            //determines if a new desktop and window station need to be created.
            //If the impersonated user already has a desktop, the system uses the
            //existing desktop.

            si.lpDesktop = @"WinSta0\Default"; //Default Vista/7 Desktop Session
            si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;

            //Check the Startup Mode of the Process 
            if (WindowMode == 1)
                si.wShowWindow = SW_SHOW;
            else if (WindowMode == 2)
            { //Do Nothing
            }
            else if (WindowMode == 3)
                si.wShowWindow = 0; //Hide Window 
            else if (WindowMode == 4)
                si.wShowWindow = 3; //Maximize Window
            else if (WindowMode == 5)
                si.wShowWindow = 6; //Minimize Window
            else
                si.wShowWindow = SW_SHOW;


            //Set other si properties as required.
            result = CreateProcessAsUser(
            token,
            null,
            cmdLine,
            ref saProcess,
            ref saThread,
            false,
            CREATE_UNICODE_ENVIRONMENT,
            envBlock,
            null,
            ref si,
            out pi);

            if (result == false)
            {
                int error = Marshal.GetLastWin32Error();
                string message = String.Format("CreateProcessAsUser Error: {0}", error);
                Debug.WriteLine(message);

            }

            return result;
        }

        private static IntPtr GetPrimaryToken(int processId)
        {
            IntPtr token = IntPtr.Zero;
            IntPtr primaryToken = IntPtr.Zero;
            bool retVal = false;
            Process p = null;

            try
            {
                p = Process.GetProcessById(processId);
            }

            catch (ArgumentException)
            {

                string details = String.Format("ProcessID {0} Not Available", processId);
                Debug.WriteLine(details);
                throw;
            }

            //Gets impersonation token
            retVal = OpenProcessToken(p.Handle, TOKEN_DUPLICATE, ref token);
            if (retVal == true)
            {

                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
                sa.nLength = (uint)Marshal.SizeOf(sa);

                //Convert the impersonation token into Primary token
                retVal = DuplicateTokenEx(
                token,
                TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY,
                ref sa,
                (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                (int)TOKEN_TYPE.TokenPrimary,
                ref primaryToken);

                //Close the Token that was previously opened.
                CloseHandle(token);
                if (retVal == false)
                {
                    string message = String.Format("DuplicateTokenEx Error: {0}", Marshal.GetLastWin32Error());
                    Debug.WriteLine(message);
                }

            }

            else
            {

                string message = String.Format("OpenProcessToken Error: {0}", Marshal.GetLastWin32Error());
                Debug.WriteLine(message);

            }

            //We'll Close this token after it is used.
            return primaryToken;

        }

        private static IntPtr GetEnvironmentBlock(IntPtr token)
        {

            IntPtr envBlock = IntPtr.Zero;
            bool retVal = CreateEnvironmentBlock(ref envBlock, token, false);
            if (retVal == false)
            {

                //Environment Block, things like common paths to My Documents etc.
                //Will not be created if "false"
                //It should not adversley affect CreateProcessAsUser.

                string message = String.Format("CreateEnvironmentBlock Error: {0}", Marshal.GetLastWin32Error());
                Debug.WriteLine(message);

            }
            return envBlock;
        }

        public static bool Launch(string appCmdLine /*,int processId*/)
        {

            bool ret = false;

            //Either specify the processID explicitly
            //Or try to get it from a process owned by the user.
            //In this case assuming there is only one explorer.exe

            Process[] ps = Process.GetProcessesByName("explorer");
            int processId = -1;//=processId
            if (ps.Length > 0)
            {
                processId = ps[0].Id;
            }

            if (processId > 1)
            {
                IntPtr token = GetPrimaryToken(processId);

                if (token != IntPtr.Zero)
                {

                    IntPtr envBlock = GetEnvironmentBlock(token);
                    ret = LaunchProcessAsUser(appCmdLine, token, envBlock);
                    if (envBlock != IntPtr.Zero)
                        DestroyEnvironmentBlock(envBlock);

                    CloseHandle(token);
                }
                
            }
            return ret;
        }

        /// <summary>
        /// Overloaded Method for Window State Mode 
        /// </summary>
        /// <param name="appCmdLine"></param>
        /// <param name="WindowMode"></param>
        /// <returns></returns>
        public static bool Launch(string appCmdLine, uint WindowMode /*,int processId*/)
        {

            bool ret = false;

            //Either specify the processID explicitly
            //Or try to get it from a process owned by the user.
            //In this case assuming there is only one explorer.exe

            Process[] ps = Process.GetProcessesByName("explorer");
            int processId = -1;//=processId
            if (ps.Length > 0)
            {
                processId = ps[0].Id;
            }

            if (processId > 1)
            {
                IntPtr token = GetPrimaryToken(processId);

                if (token != IntPtr.Zero)
                {

                    IntPtr envBlock = GetEnvironmentBlock(token);
                    ret = LaunchProcessAsUser(appCmdLine, token, envBlock,WindowMode);
                    if (envBlock != IntPtr.Zero)
                        DestroyEnvironmentBlock(envBlock);

                    CloseHandle(token);
                }

            }
            return ret;
        }

    }

    #endregion

    public class appLog
    {
    #region LogToTextFiles
        public static void WriteTextLog(string Text, string pathLog, string TaskName)
        {

            string Exedir = AppDomain.CurrentDomain.BaseDirectory;

            string filetoLog = pathLog;
            if (filetoLog == string.Empty) filetoLog = Exedir;
            if (filetoLog.Contains("%LOGDIR%")) filetoLog = filetoLog.Replace("%LOGDIR%", Exedir);
            filetoLog += @"\LOG";
            if (!System.IO.Directory.Exists(filetoLog))
                System.IO.Directory.CreateDirectory(filetoLog);

            string data = DateTime.Now.Date.Year.ToString() + DateTime.Now.Date.Month.ToString() + DateTime.Now.Date.Day.ToString();
            filetoLog += (filetoLog.EndsWith(@"\")) ? TaskName + "_" + data + @".log" : @"\" + TaskName + "_" + data + @".log";

            using (StreamWriter sw = File.AppendText(filetoLog))
            {
                sw.WriteLine(DateTime.Now + " - " + Text);
            }

        }
    #endregion
    }

    }
